<template>
  <div class="view-article-page-wrapper">
    <div class="relate-info-wrapper">
      <author-info-card
        :author="author"
        class="author-info-card"
        @fetchAuthorInfo="fetchAuthorInfo"
      ></author-info-card>

      <author-hot-article-card
        :articles="author.articles"
        class="author-hot-article-card"
      ></author-hot-article-card>

      <index-card class="index-card" :dom="articleDOM"></index-card>
    </div>

    <div class="article-wrapper">
      <article-card
        :article="articleData.article"
        :author="author"
        class="article-card"
        ref="articleCard"
        @renewIndex="renewIndex"
      ></article-card>

      <comment-card
        :comments="comments!"
        :contentType="'article'"
        @submitComment="comment"
        @fetchComments="fetchComments"
        class="comment-card"
        ref="commentCard"
      ></comment-card>
    </div>

    <ul class="operation-list">
      <li @click="like">
        <p
          class="iconfont icon-like"
          :class="{
            been: articleData.article?.likeTimes,
          }"
        ></p>
      </li>
      <li @click="collect">
        <p
          class="iconfont icon-collect"
          :class="{
            been: articleData.article?.collectTimes,
          }"
        ></p>
      </li>
      <li @click="scrollToComment">
        <p class="iconfont icon-comment"></p>
      </li>
      <li @click="share">
        <p class="iconfont icon-share"></p>
      </li>
    </ul>
  </div>
</template>

<script lang="ts" setup>
import { assertLogin } from '@/utils/assert'
import { reactive, ref, toRef, Ref, Component, watch } from 'vue'
import { useRoute } from 'vue-router'
import { post } from '@/utils/request'
import { show } from '@/utils/popup'

import ArticleCard from './components/article/ArticleCard.vue'
import AuthorInfoCard from './components/browse/AuthorInfoCard.vue'
import AuthorHotArticleCard from './components/browse/AuthorHotArticleCard.vue'
import CommentCard from './components/browse/CommentCard.vue'
import IndexCard from './components/browse/IndexCard.vue'

let articleData = reactive({} as App.ArticleData)
let author = reactive({} as App.Author)
let comments = toRef(articleData, 'comments')
let commentsPage = 0

let articleDOM: Document | null = null

const route = useRoute()
watch(route, fetchBaseInfo, {
  immediate: true,
})
function fetchBaseInfo() {
  if (typeof route.params.id != 'string') return
  articleData.id = route.params.id
  fetchArticleInfo()
  fetchAuthorInfo()
}

async function fetchArticleInfo() {
  let response = await post('article/content', {
    id: articleData.id,
  })
  let data = response.data as App.Article
  articleData.article = data
  fetchAuthorInfo()
}

async function fetchAuthorInfo() {
  if (articleData.author === undefined) return
  let authorInfo = (
    await post('author/info', {
      author_id: articleData.author.id,
    })
  ).data as App.Author
  articleData.author = authorInfo
  let authorHotArticle = (
    await post('author/article', {
      page: 1,
      id: articleData.author.id,
      sort: 0,
    })
  ).data as App.Article[]
  author.articles = authorHotArticle.slice(0, 5)
}

async function fetchComments() {
  try {
    let response = await post('article/content/comment', {
      id: articleData.id,
      page: ++commentsPage,
    })
    comments.value!.concat(response.data as App.Comment[])
  } catch {
    commentsPage--
  }
}

function like() {
  try {
    assertLogin()
    post('article/content/like', {
      id: articleData.id,
    })
    show('点赞/取消成功')
  } catch {
    show('点赞/取消失败')
  }
}

function comment(content: string) {
  try {
    assertLogin()
    post('/article/content/comment/submie', {
      content,
      id: articleData.id,
    })
  } catch {
    show('评论失败')
  }
}

function collect() {
  try {
    assertLogin()
    post('article/content/collect', {
      id: articleData.id,
    })
    show('收藏成功')
  } catch {
    show('收藏失败')
  }
}

function share() {
  const input = document.createElement('input')
  input.style.opacity = '0'
  document.body.appendChild(input)
  input.setAttribute('value', location.href)
  input.select()
  if (document.execCommand('copy')) {
    show('已复制网址')
  }
  document.body.removeChild(input)
}

function renewIndex(dom: Document) {
  articleDOM = dom
}

let commentCard: Ref<Component | null> = ref(null)
function scrollToComment() {
  let dom = (commentCard.value as any).$el as any
  dom.scrollIntoView({
    behavior: 'smooth',
    top: 0,
  })
}
</script>

<style lang="scss" scoped>
@import 'style/shortcut';

.view-article-page-wrapper {
  display: flex;
  justify-content: space-between;

  width: var(--innerWidth);
  --w1: calc(var(--innerWidth) * 0.28);
  --w2: calc(var(--innerWidth) * 0.71);
  margin: calc(var(--topNavHeight) + 10px) auto;

  .relate-info-wrapper {
    width: var(--w1);

    .author-info-card {
      --authorInfoCardWidth: var(--w1);
      --authorInfoCardHeight: 250px;
    }

    .author-hot-article-card {
      margin-top: 10px;
      --authorHotArticleCardWidth: var(--w1);
    }

    .index-card {
      position: sticky;
      top: 20px;
      margin-top: 10px;
      --indexCardWidth: var(--w1);
    }
  }

  .article-wrapper {
    float: right;
    width: var(--w2);

    .article-card {
      --articleCardWidth: var(--w2);
    }

    .comment-card {
      margin-top: 20px;
      --commentCardWidth: var(--w2);
    }
  }

  .operation-list {
    position: fixed;
    top: 50%;
    right: 0;
    height: 300px;
    transform: translateY(-150px);
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: space-between;

    li {
      width: 50px;
      text-align: center;

      p {
        font-size: 25px;
        width: 50px;
        height: 50px;
        line-height: 50px;
        background-color: white;
        border-radius: 50%;

        &:hover,
        &.been {
          cursor: pointer;
          color: white;
          background-color: var(--blue);
        }
      }
    }
  }
}
</style>
